package com.logic.modular.game.battle.panel.skillEffect.base;

import com.logic.comment.util.BeanUtil;
import com.logic.comment.util.RedisUtils;
import com.logic.modular.game.battle.panel.skillEffect.PvpSkillEffect;
import lombok.extern.slf4j.Slf4j;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.stream.Collectors;

@Slf4j
public class PvpSkillEffectBaseService {
    public static final String SKILL_EFFECT_PANEL_KEY1 = "battle:%d:skillEffect";
    /**
     * 英雄id:{playerHeroId}-技能效果id:{coreSkillEffectTypeId}-技能类型:{coreSkillTyp}
     */
    public static final String SKILL_EFFECT_PANEL_KEY2 = "%d-%d-%d";
    @Resource
    public RedisUtils redisUtils;

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public List<PvpSkillEffect> eqList(PvpSkillEffect select) {
        String key = String.format(SKILL_EFFECT_PANEL_KEY1, select.getBattleId());
        return redisUtils.hValues(key).stream().map(object -> (PvpSkillEffect) object)
                .filter(eqSelector(select))
                .collect(Collectors.toList());
    }

    public static Predicate<PvpSkillEffect> eqSelector(PvpSkillEffect select) {
        Long battleId = select.getBattleId();
        if (battleId == null) {
            throw new RuntimeException("battleId不能为空");
        }
        return PvpSkillEffect ->
                new BeanUtil.Selector()
                        .eq(select.getBattleId(), PvpSkillEffect.getBattleId())
                        .eq(select.getSourcePlayerHeroId(), PvpSkillEffect.getSourcePlayerHeroId())
                        .eq(select.getTargetPlayerHeroId(), PvpSkillEffect.getTargetPlayerHeroId())
                        .eq(select.getSourceCoreSkillId(), PvpSkillEffect.getSourceCoreSkillId())
                        .eq(select.getSourceCoreSkillStarId(), PvpSkillEffect.getSourceCoreSkillStarId())
                        .eq(select.getTargetPlayerHeroId(), PvpSkillEffect.getTargetPlayerHeroId())
                        .eq(select.getCoreSkillTyp(), PvpSkillEffect.getCoreSkillTyp())
                        .eq(select.getCoreSkillEffectTypeId(), PvpSkillEffect.getCoreSkillEffectTypeId())
                        .value();
    }

    public PvpSkillEffect eqSelect(PvpSkillEffect select) {
        return eqList(select).stream().findFirst().orElse(null);
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    public void saveCache(PvpSkillEffect pvpSkillEffect) {
        pvpSkillEffect.status.triggerFailReasons = new HashMap<>();

        Long battleId = pvpSkillEffect.getBattleId();
        Long targetPlayerHeroId = pvpSkillEffect.getTargetPlayerHeroId();
        Long coreSkillEffectTypeId = pvpSkillEffect.getCoreSkillEffectTypeId();
        Integer coreSkillTyp = pvpSkillEffect.getCoreSkillTyp();
        String key1 = String.format(SKILL_EFFECT_PANEL_KEY1, battleId);
        String key2 = String.format(
                SKILL_EFFECT_PANEL_KEY2,
                targetPlayerHeroId,
                coreSkillEffectTypeId,
                coreSkillTyp
        );
        redisUtils.hPut(key1, key2, pvpSkillEffect, 20, TimeUnit.MINUTES);
    }
    public List<PvpSkillEffect> list(Long battleId) {
        String key = String.format(SKILL_EFFECT_PANEL_KEY1, battleId);
        if (key.contains("null")) {
            throw new RuntimeException("key1不能为空");
        }
        return redisUtils.hGetAll(key).values().stream()
                .map(object -> (PvpSkillEffect) object)
                .collect(Collectors.toList());
    }

    public List<PvpSkillEffect> list(Long battleId, Long playerHeroId) {
        String key = String.format(SKILL_EFFECT_PANEL_KEY1, battleId);
        if (key.contains("null")) {
            throw new RuntimeException("key1不能为空");
        }
        Set<Object> objects = redisUtils.hKeys(key);

        return objects.stream()
                .filter(object -> object.toString().startsWith(playerHeroId.toString() + "-"))
                .map(object -> (PvpSkillEffect) redisUtils.hGet(key, object.toString()))
                .collect(Collectors.toList());
    }

    public void remove(Long battleId, Long playerHeroId, Long effectTypeId, Integer coreSkillTyp) {
        String key1 = String.format(SKILL_EFFECT_PANEL_KEY1, battleId);
        String key2 = String.format(
                SKILL_EFFECT_PANEL_KEY2,
                playerHeroId,
                effectTypeId,
                coreSkillTyp
        );
        if (key1.contains("null")) {
            throw new RuntimeException("key1不能为空");
        }
        redisUtils.hDelete(key1, key2);
    }

    public Boolean has(
            Long battleId,
            Long playerHeroId,
            Long coreSkillEffectTypeId,
            Integer coreSkillTyp
    ) {
        String key1 = String.format(SKILL_EFFECT_PANEL_KEY1, battleId);
        if (key1.contains("null")) {
            throw new RuntimeException("key1不能为空");
        }
        String key2 = String.format(SKILL_EFFECT_PANEL_KEY2,
                playerHeroId,
                coreSkillEffectTypeId,
                coreSkillTyp
        );
        return redisUtils.hExists(key1, key2);
    }

}
